package com.example.sudokugame.views

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import com.example.sudokugame.models.SudokuCell
import kotlin.math.min

class SudokuGridView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private var grid: Array<Array<SudokuCell>> = Array(9) { Array(9) { SudokuCell() } }
    private var selectedRow = -1
    private var selectedCol = -1
    
    private var cellSize = 0f
    private var gridSize = 0f
    private var offsetX = 0f
    private var offsetY = 0f
    
    // 画笔
    private val linePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.BLACK
        strokeWidth = 2f
        style = Paint.Style.STROKE
    }
    
    private val thickLinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.BLACK
        strokeWidth = 6f
        style = Paint.Style.STROKE
    }
    
    private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.BLACK
        textAlign = Paint.Align.CENTER
        textSize = 48f
        typeface = Typeface.DEFAULT_BOLD
    }
    
    private val hintTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.BLUE
        textAlign = Paint.Align.CENTER
        textSize = 48f
        typeface = Typeface.DEFAULT_BOLD
    }
    
    private val errorTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.RED
        textAlign = Paint.Align.CENTER
        textSize = 48f
        typeface = Typeface.DEFAULT_BOLD
    }
    
    private val fixedTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.DKGRAY
        textAlign = Paint.Align.CENTER
        textSize = 48f
        typeface = Typeface.DEFAULT_BOLD
    }
    
    private val selectedCellPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#E3F2FD")
        style = Paint.Style.FILL
    }
    
    private val highlightPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#F5F5F5")
        style = Paint.Style.FILL
    }
    
    // 回调接口
    interface OnCellSelectedListener {
        fun onCellSelected(row: Int, col: Int)
    }
    
    private var onCellSelectedListener: OnCellSelectedListener? = null
    
    fun setOnCellSelectedListener(listener: OnCellSelectedListener) {
        this.onCellSelectedListener = listener
    }
    
    fun setGrid(newGrid: Array<Array<SudokuCell>>) {
        this.grid = newGrid
        invalidate()
    }
    
    fun getGrid(): Array<Array<SudokuCell>> = grid
    
    fun setSelectedCell(row: Int, col: Int) {
        selectedRow = row
        selectedCol = col
        invalidate()
    }
    
    fun clearSelection() {
        selectedRow = -1
        selectedCol = -1
        invalidate()
    }
    
    fun setCellValue(row: Int, col: Int, value: Int) {
        if (row in 0..8 && col in 0..8 && !grid[row][col].isFixed) {
            grid[row][col].value = value
            grid[row][col].isError = false
            invalidate()
        }
    }
    
    fun setCellError(row: Int, col: Int, isError: Boolean) {
        if (row in 0..8 && col in 0..8) {
            grid[row][col].isError = isError
            invalidate()
        }
    }
    
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val width = MeasureSpec.getSize(widthMeasureSpec)
        val height = MeasureSpec.getSize(heightMeasureSpec)
        val size = min(width, height)
        setMeasuredDimension(size, size)
    }
    
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        gridSize = min(w, h).toFloat()
        cellSize = gridSize / 9f
        offsetX = (w - gridSize) / 2f
        offsetY = (h - gridSize) / 2f
        
        // 调整文字大小
        textPaint.textSize = cellSize * 0.6f
        hintTextPaint.textSize = cellSize * 0.6f
        errorTextPaint.textSize = cellSize * 0.6f
        fixedTextPaint.textSize = cellSize * 0.6f
    }
    
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        
        // 绘制背景高亮
        drawHighlights(canvas)
        
        // 绘制选中单元格
        drawSelectedCell(canvas)
        
        // 绘制网格线
        drawGridLines(canvas)
        
        // 绘制数字
        drawNumbers(canvas)
    }
    
    private fun drawHighlights(canvas: Canvas) {
        if (selectedRow in 0..8 && selectedCol in 0..8) {
            // 高亮选中行和列
            for (i in 0..8) {
                // 高亮行
                canvas.drawRect(
                    offsetX,
                    offsetY + selectedRow * cellSize,
                    offsetX + gridSize,
                    offsetY + (selectedRow + 1) * cellSize,
                    highlightPaint
                )
                
                // 高亮列
                canvas.drawRect(
                    offsetX + selectedCol * cellSize,
                    offsetY,
                    offsetX + (selectedCol + 1) * cellSize,
                    offsetY + gridSize,
                    highlightPaint
                )
            }
            
            // 高亮3x3区域
            val boxRow = selectedRow / 3
            val boxCol = selectedCol / 3
            canvas.drawRect(
                offsetX + boxCol * 3 * cellSize,
                offsetY + boxRow * 3 * cellSize,
                offsetX + (boxCol + 1) * 3 * cellSize,
                offsetY + (boxRow + 1) * 3 * cellSize,
                highlightPaint
            )
        }
    }
    
    private fun drawSelectedCell(canvas: Canvas) {
        if (selectedRow in 0..8 && selectedCol in 0..8) {
            canvas.drawRect(
                offsetX + selectedCol * cellSize,
                offsetY + selectedRow * cellSize,
                offsetX + (selectedCol + 1) * cellSize,
                offsetY + (selectedRow + 1) * cellSize,
                selectedCellPaint
            )
        }
    }
    
    private fun drawGridLines(canvas: Canvas) {
        // 绘制细线
        for (i in 0..9) {
            val paint = if (i % 3 == 0) thickLinePaint else linePaint
            
            // 垂直线
            canvas.drawLine(
                offsetX + i * cellSize,
                offsetY,
                offsetX + i * cellSize,
                offsetY + gridSize,
                paint
            )
            
            // 水平线
            canvas.drawLine(
                offsetX,
                offsetY + i * cellSize,
                offsetX + gridSize,
                offsetY + i * cellSize,
                paint
            )
        }
    }
    
    private fun drawNumbers(canvas: Canvas) {
        for (row in 0..8) {
            for (col in 0..8) {
                val cell = grid[row][col]
                if (!cell.isEmpty) {
                    val x = offsetX + col * cellSize + cellSize / 2f
                    val y = offsetY + row * cellSize + cellSize / 2f + textPaint.textSize / 3f
                    
                    val paint = when {
                        cell.isError -> errorTextPaint
                        cell.isHinted -> hintTextPaint
                        cell.isFixed -> fixedTextPaint
                        else -> textPaint
                    }
                    
                    canvas.drawText(cell.value.toString(), x, y, paint)
                }
            }
        }
    }
    
    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_DOWN) {
            val x = event.x
            val y = event.y
            
            if (x >= offsetX && x <= offsetX + gridSize && 
                y >= offsetY && y <= offsetY + gridSize) {
                
                val col = ((x - offsetX) / cellSize).toInt()
                val row = ((y - offsetY) / cellSize).toInt()
                
                if (row in 0..8 && col in 0..8) {
                    selectedRow = row
                    selectedCol = col
                    invalidate()
                    onCellSelectedListener?.onCellSelected(row, col)
                    return true
                }
            }
        }
        return super.onTouchEvent(event)
    }
} 